
ffi = _G.old_require("ffi")
local Config = require("Config")
local Grid = require("bag.Grid")
local ShopHelp = require("shop.ShopHelp")


ROLE_SIZE = ROLE_SIZE or 0
--GRID_SIZE = GRID_SIZE or 0
--TASK_RECORD_SIZE = TASK_RECORD_SIZE or 0
--BUFFER_RECORD_SIZE = BUFFER_RECORD_SIZE or 0
function init()
    ffi.cdef[[
    void  role_list_init(int max_fd, int role_cap, int role_size);
    void* role_alloc();
    void  role_free(void* role);
    int   role_add(void* role, int fd);
    int   role_copy(void* dst, void* src, int size);
    void  memset_zero(void* p, int size);
    void* find_role_by_fd(int fd);
    void* find_role_by_account(char* account);
    void* find_role_by_name(char* name);

    struct grid{
        unsigned short id;
        unsigned short cnt;
        char bind;
        char open;
        char uuid[128];
        unsigned int createTime;
        unsigned int lifeTime;
        union {
            struct{
                char cntLimit;
                char cntIndex;
            } item;
            struct{
                char quality;
                char hole;
                unsigned short gems[5];
                unsigned short strengthLv;
                unsigned short xiLianStar[4];
                unsigned short xiLianAttr[4];
                double xiLianAttrVal[4];
                unsigned short xiLianTimes;
                unsigned short xiLianPower;
                unsigned int power;
            } equip;
        }data;
    };

    struct task_record{
        short taskid;
        char  status;
        char  finishFlag;
        struct{
            int target;
            short num;
        } params[10];
        char paramsLen;
    };
    struct buffer_record{
        int id;
        short count;
        char  skillLevel;
        char  firstRun;
        short tx;
        short ty;
        int sendID;
        double sendUID;
        double time;
        double lastTime;
        double startTime;
        double param;
     };
     
     struct offlinepk_log {
          unsigned char name[64];
          unsigned int  time;
          unsigned char win;
          unsigned char result;
          unsigned char active;
          unsigned int  rank;          
     };
    typedef struct {
        int svrIndex;
        char middleFlag;
        char familyUuidM[128];
        char familyNameM[64];
        char familyLvM;
        char _id[128];
        char account[64];
        char name[64];

        short map_id;
        short x;
        short y;
        char lv;
        char sex;
        short head;
        char fcm;
        unsigned int  olTime;
        unsigned int  yinliang;   
        unsigned int  yuanbao;
        unsigned int  bind_yuanbao;
        unsigned int  precost_yinliang; //不需要保存到数据库
        unsigned int  precost_yuanbao;  //不需要保存到数据库
        unsigned int  zhangong;
        unsigned int  wushuang;
        unsigned int  prestige;
        unsigned int  prestigeHistory;
        unsigned int  rongyu;
        unsigned int  historyYuanbao;
        double rmb;
        unsigned char firstPay;
        unsigned int  lastPayTime;
        unsigned int  everyDayPay;
        unsigned int  hp;
        unsigned int  mp;
        unsigned double  exp;
        unsigned int  lastLoginTime;
        unsigned int  lastLogoutTime;
        unsigned char disconnect;  //不需要保存到数据库
        unsigned int  lastCG;   //不需要保存数据库
        //QQ平台相关参数，不需要保存到数据库
        char openid[64];
        char openkey[64];
        char pf[64];
        char pfkey[64];
        char yellowYearVip; //不需要保存到数据库
        char yellowVip;//不需要保存到数据库
        char yellowVipLv;//不需要保存到数据库
        char blueYearVip;//不需要保存到数据库
        char blueVip;//不需要保存到数据库
        char blueVipLv;//不需要保存到数据库
        char blueSuperVip;
        unsigned int blueVipValidTime;
        unsigned int blueYearValidTime;
        unsigned int blueSuperValidTime;
        unsigned char level3366;        
        char isMiniClient;
        //QQ end
        //QQ 任务集市
        char appContractId[64];
        unsigned short appContractIdStatus;
        //
        
        char hide; //是否设置隐藏，不需要保存到数据库
        
        char ip[16];

        char gm;
        double ban_say_time;

        struct {
            short  id;
            double time;
            char   count;
        } cooldown[45];
        char cooldownLen;

        unsigned int zhandouli;


        double dieTime;
        short copyDieCount;
        char killerName[64];
        short killerType;


        struct buffer_record buf[32];
        char bufLen;


        struct grid bag[288];
        short bagLen;
        struct grid equip[13];
        char equipLen;
        struct grid store[336];
        short storeLen;
        unsigned int update_daily_time;

        struct {
            short copy_id;
            char  times;
            char  addCnt;
        } copyTimes[100];
        char copyTimesLen;
        short copyEnterMap;
        short copyEnterX;
        short copyEnterY;        
        short preMapID;
        short preMapX;
        short preMapY;
        char isAutoAddFriend;
        struct {
            char uuid[128];
            unsigned int create_time;
        } black[100];
        int blackLen;
        struct {
            char uuid[128];
            short revengeTimes;
            short killedTimes;
        } enemy[20];
        int enemyLen;
        unsigned int MaxHp; //不需要保存到数据库
        unsigned int MaxMp; //不需要保存到数据库
        struct {
            char uuid[128];
        } teamUuid[5];   //不需要保存到数据库
        char teamUuidLen;//不需要保存到数据库

        struct task_record taskRecord[256];
        short taskRecordLen;
        unsigned char   taskGroupCnt;
        unsigned char   taskGroupAddCnt;
        struct {
            char id;
            short lv;
            char  deng;
            char  star;
            char  jinhua;
            char  jueji;
            unsigned short skillLv[4];
            unsigned int zhandouli;
            unsigned int feedAttr[8];
        } shenbing[10];
        char shenbingLen;
        char putonShenbing;

        unsigned short horseStarLv;
        char isMount;
        unsigned short chooseHorseId;
        unsigned short horseUpVal;
        struct {
          unsigned short haveHorseId;
          unsigned int limitTime;
          double startTime;
          unsigned short skillLv;
          unsigned char horseXX;
          unsigned short equipQua;
          unsigned short equipId[4];
          unsigned int feedAttr[8];
        }haveHorse[10];
        char haveHorseLen;
        unsigned short horseSkillLv;
        unsigned short horseWishVal;
        unsigned short upStageTimes;
        char horseStageLv;
        unsigned char horseXX[10];
        struct{
          unsigned short equipQua;
          unsigned short equipId[4];
          unsigned int feedAttr[8];        
        }stageHorse[10];
        unsigned char stageHorseLen;

        char familyUuid[128];
        char familyName[128];
        unsigned int familyExitTime;
        unsigned int familyAlgContributionRmb;

        struct {
            char uuid[128];
            unsigned applyTime;
        } familyApplyList[100];
        char familyApplyListLen;

        unsigned int familyContribution;
        unsigned short familyLv;
        unsigned short familyBanner;
        unsigned char  familyWarResult;

        struct {
            unsigned short strategyLev;
        } familyStrategyList[100];
        char familyStrategyListLen;

        struct {
            unsigned short index;
            unsigned short state;
        } familyShopList[100];
        char familyShopListLen;
        unsigned familyContributionShopFlushTime;
        unsigned int familyShopFlushCnt;
        unsigned int familyOnHookBuyTime;
        unsigned int familyOnHookTime;
        unsigned int familyReject;

        struct {
            unsigned short index;
            unsigned short state;
            unsigned short itemID;
        } mysteryRmbShopList[100];
        char mysteryRmbShopListLen;
        unsigned mysteryRmbShopFlushTime;
        unsigned mysteryRmbShopFlushCnt;

        struct {
            unsigned short index;
            unsigned short state;
            unsigned short itemID;
            unsigned short curCount;
        } mysteryPrestigeShopList[100];
        char mysteryPrestigeShopListLen;

        double zhangongHistory;

        struct {
            unsigned short index;
            unsigned short state;
            unsigned short itemID;
            unsigned short curCount;
        } mysteryHonorShopList[100];
        char mysteryHonorShopListLen;

        unsigned short jumpValue;

        unsigned short awakeVal;
        struct grid gridRebuy[24];
        unsigned char gridRebuyLen;

        unsigned char bountyDoCnt;
        unsigned char bountyLv;
        unsigned char bountyFreeTimes;
        unsigned int  bountyRefreshTime;
        unsigned int  bountyCanDoList[10];
        unsigned char bountyCanDoListLen;
        unsigned char bountyAddCnt;
        struct{
            unsigned short key;
            double value;
            unsigned char star;
        }xilianAttrTemp[4];

        struct {
            unsigned short itemid;
            unsigned short cnt;
        } item_use_cnt[128];
        unsigned char item_use_cntLen;

        struct {
            unsigned short group;
            unsigned short cnt;
        } item_use_group[128];
        unsigned char item_use_groupLen;

        struct {
            unsigned short group;
            unsigned int usetime;
        } item_use_cool[128];
        unsigned char item_use_coolLen;
        
        struct {
            unsigned short itemid;
            unsigned short cnt;
        } attr_item[30];
        unsigned char attr_itemLen;
        
        unsigned short shopLimtiCnt[900];
        
        struct{
          unsigned char lv;
          unsigned int exp;
          unsigned short id;
          unsigned int hp;
          char status;
          char star;
          unsigned short stage;
          unsigned short equipStatus[4];
          unsigned int feedAttrVal[8];
          unsigned short skillLv[4];
          unsigned int zhandouli;
          double next_create_time;
          unsigned int startTime;
          unsigned int limitTime;
        }pet[20];
        unsigned short petLen;  
        unsigned short petCombatId;
        unsigned char petAtticLv;
        unsigned short petAtticPro;        
        
        unsigned int loginKeepDay;
        unsigned char loginChange;
        unsigned char fuliIsGet[15 * 11];
        unsigned char signDay[31];
        unsigned short investRMB;
        unsigned short findCowryTimes;
        unsigned short cowrySpecTimes;
        struct{
          unsigned short maxGetIndex;
          unsigned short maxGetTimes;
        } cowryGetMaxCnt[65];
        unsigned short cowryGetMaxCntLen;
        struct grid cowryBag[168];
        unsigned short cowryBagLen;
        unsigned int onLineSeconds;   
        struct{
          unsigned short id;
          unsigned short cnt;
          unsigned short bind;
        } cowryRecord[20];
        unsigned short cowryRecordLen;
        unsigned char fuliGrowBuyTimes[55];
        
        unsigned char rmbSmeltTimes;
        unsigned char yestdaySmeltTimes;
        unsigned char rmbSmelthelpTimes;
        unsigned char rmbSmeltIsPut;
        char helpUuid[128]; 
        unsigned int humanSet;
        
        unsigned int actValue;
        struct {
          unsigned char id;
          unsigned char cnt;
        } actValueRecord[32];
        unsigned char actValueRecordLen;
        unsigned int  actValueRewardOk;
        
        unsigned char pata_cur;
        unsigned char pata_max;
        unsigned char pata_reset;
        unsigned char pata_add;
        unsigned char pata_ko;
        struct grid   pata_store[18];
        unsigned char pata_storeLen;
        unsigned char pata_first[30];
        unsigned char pata_ko_reward;
        unsigned char pata_first_die;
                
        struct{
          unsigned int startTime;
          unsigned char isGet;
          unsigned short times;
        }monthCard[2];
        unsigned char vipRewardIsGet[12];
        unsigned char monthCardAddBag;
        
        struct {
            char uuid[128];
        } worship[10];
        char worshipLen;            
        unsigned int worshipedTimes;    
        
        char wsAddTimes;
        unsigned short remainTZ;

        
        
        unsigned char status;//不需要保存数据库的字段
        unsigned char fight; //不需要保存数据库的字段
        
        unsigned int dailyChongzhi;
        unsigned char openActStatus[56];
        unsigned char openActBuyTimes[8];
        unsigned int dailyCostBindYunabao;
        unsigned short openActDrawTimes;
        unsigned short openActDrawTotalTimes;
        
        unsigned char autoUseDrugPer; 
        
        unsigned short market_bagPos;//临时寄售数据，不保存数据库
        unsigned short market_bagCnt;//临时寄售数据，不保存数据库
        
        unsigned int wsslTime;
        
        unsigned int offlinePkRank;
        unsigned int offlinePkRewardRank;
        unsigned int offlinePkHistoryRank;
        unsigned int offlinePkTime;
        struct offlinepk_log offlinePkLogs[10];
        unsigned char offlinePkLogsLen;
        unsigned int jzwarEnterTime;
        unsigned int dhfightEnterTime;
        unsigned int ccjjwarEnterTime;
        
        unsigned char yellowNewReward;
        unsigned char yellowLvReward[20];
        unsigned char yellowDailyReward[10];
        
        unsigned char tgpNew;
        unsigned char tgpLv[10];
        unsigned char tgpDaily;
        unsigned char tgpWeek;
        
        unsigned int riotContribution;
        unsigned int riotFamilyExp;

        double reviveNowTime;
        unsigned int reviveNowItemNum;
        
        struct{
          unsigned char lv;
          unsigned short exp;
        } xlLv[13];
        unsigned char xlLvLen;   
        
        struct{          
          unsigned char id;
          unsigned short starLv;          
          unsigned short lv;
          unsigned int exp;
          unsigned short skillId;
          unsigned short skillLv;
          unsigned char status;
          unsigned int power;
          unsigned short LonghunLv;
          unsigned short leftSkillId;
          unsigned short rightSkillId;
          unsigned int startTime;
          unsigned int limitTime;
        } baowu[10];
        unsigned char baowuLen;
        unsigned char combatBaowu;    
        
        unsigned int YYActivityId[40];
        unsigned char YYChongzhiRebate[10];
        unsigned short YYChongzhiDrawTimes;
        unsigned short YYCritDrawTimes;
        unsigned char YYLimitBuyTimes[40];
        unsigned char YYDaBiaoStatus[7 * 8]; 
        unsigned char YYChongzhiDrawIndex;//充值抽奖抽中索引
        double YYChongzhiDrawMulti;//充值抽奖抽中索引
        unsigned char YYPayDrawIndex[10];
        unsigned short skillItemList[2];
        unsigned char YYCopyFastIsGet;
        unsigned char YYActivityPlayIsGet[15];      
        unsigned char YYPayDrawStatus[10];
        unsigned short YYPayDrawTimes;
        
        struct{
          unsigned short id;
          unsigned char copyFreeFindTimes;
          unsigned char copyYuanbaoFindTimes;
          unsigned char copyYestdayFreeFindTimes;
          unsigned char copyYestdayYuanbaoFindTimes;
        }copyFind[12];
        unsigned char copyFindLen;
        struct{
          unsigned short id;
          unsigned char actFindType;          
          unsigned char actYestdayFindType;
          unsigned char actYuanbaoFindType;
          unsigned char actYuanbaoYestdayFindType;
        }ActFind[12];
        unsigned char ActFindLen;
        unsigned char ChongzhiPresentCnt;
        unsigned int dailyCostYuanbao;
        struct{
          unsigned short type;
          unsigned short sumCnt;
          unsigned short dailyCnt;
          unsigned int getTime;
        }activateHis[20];
        unsigned char activateHisLen;

        unsigned char blueNewReward;
        unsigned char blueLvReward[20];
        unsigned char blueDailyReward[10];
        
        unsigned char level3366CanGet[6];    //3366礼包能领取的最大ID
        
        unsigned int DateActivityId[40];
        unsigned short DateCritDrawTimes;
        unsigned char DateLimitBuyTimes[40];
        unsigned char DateChongzhiRebate[10];  
        unsigned char DatePayDrawStatus[10];
        unsigned short DatePayDrawTimes;
        unsigned char DateCritDrawIndex;   //不保存到数据库

        unsigned int curarmourid;
        struct{
            unsigned int armourid;
            unsigned int lv;
            unsigned int star;
            unsigned int state;
            unsigned int feedAttr[8];
        } armourlist[32];
        unsigned int armourlistLen;
        
        unsigned char dailyGiftStatus;
        unsigned char dailyGiftThirdID;
        
        struct{
            unsigned char id;
            unsigned short skillLv;
            unsigned char status;
        } yaoshuList[20];
        unsigned char yaoshuListLen;
        unsigned int QiliaoSkillLv;
        unsigned char combatYaoshu;
        unsigned short dhfightcurfloor;
        
        unsigned int taoyuanLastFreeTime;
        char taoyuanReward[5];
        unsigned int taoyuanVersion;
        unsigned char canFindExpHour;//可找回几个小时的经验
        
        struct {
            unsigned char id;
            unsigned int  createTime;
        }titleList[16];
        unsigned char titleListLen;
        unsigned char titleSelectID;
        
        unsigned double officialTarget[25];
        unsigned char officialRewardIsGet;
        unsigned char officialLv;
    }role;
    ]]

    ROLE_SIZE = ffi.sizeof('role')
--    GRID_SIZE = ffi.sizeof('struct grid')
--    TASK_RECORD_SIZE = ffi.sizeof('struct task_record')
--    BUFFER_RECORD_SIZE = ffi.sizeof('struct buffer_record')
    local cap = 3000
    if Config.IS_LITTLE_MEM then
        cap = 50
    end
    ffi.C.role_list_init(32768, cap,  ffi.sizeof('role'))
    
    print("ROLE_SIZE:", ROLE_SIZE)
end


local function del_child_template(db)
    for _,v in pairs(db) do
        if type(v) == "table" then
            v.child_template = nil
            del_child_template(v)
        end
    end
end

--[[lua层玩家数据结构，不能有nil值的，必须和 c层role结构对应
--   基本数据类型的数组：
LUA:    a = {}, aLen = 0 数字型数组
C:      int a[100], aLen = 0
--   自定义类型数组：
LUA:    skill ={child_template={id = 0, level = 0}  skillLen = 0
C:      struct { int id = 0, level = 0} skill[100]; int skillLen = 0
--
--]]
function get_default_db(template)
    local db = {
        _id = "",
        svrIndex = Config.SVR_INDEX,
        -- 跨服用字段
        middleFlag = 0,
        familyUuidM = "",
        familyNameM = "",
        familyLvM = 0,
        -- 跨服end
        account = "",
        name = "",
        map_id = 9999,
        x = 1555,
        y = 2541,
        lv = 1,
        sex = 1,
        head = 0,
        fcm = 0,
        olTime = 0,             -- 当日在线时间
        yinliang = 0,           -- 银俩
        bind_yuanbao = 0,       -- 绑定元宝
        yuanbao = 0,            -- 元宝
        zhangong = 0,           -- 战功值
        wushuang = 0,           -- 无双值
        prestige = 0,           -- 威望
        prestigeHistory = 0,    -- 累计威望值
        rongyu = 0,             -- 荣誉值
        historyYuanbao = 0,     -- 累冲
        rmb = 0,                 -- 充值
        firstPay = 0,           -- 首充领奖记录
        lastPayTime = 0,        -- 最后一次充值时间
        everyDayPay = 0,      -- 每日首充元宝（每日首充元宝使用）
        hp = 0x7fffffff,
        mp = 0x7fffffff,
        exp = 0,
        lastLoginTime = 0,
        lastLogoutTime = 0,
        ip = "",
        gm = 0,
        ban_say_time = 0,
        cooldown = {child_template = {id = 0, time= 0, count = 0}},--数组模式
        cooldownLen = 0,
        zhandouli = 0,

        buf = {child_template = {id = 0, count= 0, skillLevel = 0, firstRun = 0, tx = 0, ty = 0, sendID = 0, sendUID= 0, time = 0, lastTime=0, startTime = 0, param = 0}},
        bufLen = 0,
        --背包，装备，宝石特殊拷贝
        bag = {},
        bagLen = 48,
        equip={},
        equipLen = 13,
        store = {},
        storeLen = 56,
        update_daily_time = 0, --每天更新时间（每天需要清理的数据的清理时间）
        copyTimes = {child_template={copy_id = 0, times = 0, addCnt = 0}},   --副本次数 , 第三个参数为vip 已增加的次数
        copyTimesLen = 0,
        copyEnterMap = 0,     --副本进入点
        copyEnterX = 0,       --副本进入点X
        copyEnterY = 0,       --副本进入点Y

        preMapID = 0,       --上一个地图ID
        preMapX = 0,        --上一个地图点X
        preMapY = 0,        --上一个地图点Y

        isAutoAddFriend = 0, --是否自动添加好友
        black = {child_template = {uuid = "", create_time = 0}},         --黑名单
        blackLen = 0,
        enemy = {child_template = {uuid = "", revengeTimes = 0, killedTimes = 0}}, --仇人
        enemyLen = 0,

        taskRecord = { child_template = {taskid = 0, status = 0, finishFlag = 0,params = {child_template={target =0, num = 0}},paramsLen = 0}}, --任务记录
        taskRecordLen = 0,
        taskGroupCnt = 0, -- 日常任务次数
        taskGroupAddCnt = 0, --增加日常任务次数

        shenbing = {child_template = {id = 0, lv = 0, deng = 0, star = 0, jinhua = 0,jueji=0, skillLv = {[0] = 0, 0, 0,0}, zhandouli = 0,feedAttr={[0]=0,0,0,0,0,0,0,0}}}, -- 神兵系统
        shenbingLen = 0,
        putonShenbing = 0, --是否已选择神兵

        horseStarLv = 0, --坐骑星级
        isMount = 1,      --是否已上坐骑，0为未上，1为已上
        chooseHorseId = 1,--当前选择的坐骑id
        horseUpVal = 0,   --当前坐骑升级值
        haveHorse = {child_template = {haveHorseId = 0, limitTime = 0, startTime = 0, skillLv = 0, horseXX = 0, equipQua = 0, equipId = {[0] = 0,0,0,0}, feedAttr = {[0] = 0,0,0,0,0,0,0,0}}},  --已经获得幻化坐骑
        haveHorseLen = 0, --获得幻化坐骑数量
        horseSkillLv = 0, --坐骑技能等级
        horseWishVal = 0, --坐骑祝福值
        horseStageLv = 1, --坐骑阶数
        horseXX = {[0] = 0,0,0,0,0,0,0,0,0,0}, --坐骑星星
        stageHorse = {child_template = {equipQua = 0, equipId = {[0] = 0,0,0,0}, feedAttr = {[0] = 0,0,0,0,0,0,0,0}}},
        stageHorseLen = 10,
        
        familyUuid = "",                --军团uuid
        familyName = "",                --军团名称
        familyExitTime = 0,             --退出军团时间
        familyWarResult = 0,            --军团赛结果
        familyLv = 0,
        familyBanner = 0,
        familyAlgContributionRmb = 0,  --每日军团已捐献元宝数
        familyShopFlushCnt = 0,         --军团限购商店刷新次数
        familyApplyList = {child_template ={uuid="",applyTime = 0}},
        familyApplyListLen = 0,
        familyContribution = 0,     --军团贡献

        familyStrategyList = {child_template = {strategyLev = 0}},                --军团韬略数据
        familyStrategyListLen = 6,              --军团韬略长度
        familyShopList = {child_template = {index = 0, state = 0}},                    --军团商店
        familyShopListLen = 0,
        familyContributionShopFlushTime = 0,
        familyOnHookBuyTime = 0,                                                    --军团挂机副本购买时间
        familyOnHookTime = 0,                                                       --军团挂机副本已用时间
        familyReject = 0,                                                           --军团拒绝邀请标志

        mysteryRmbShopList = {child_template = {index = 0, state = 0, itemID = 0}},             --珍宝元宝商店
        mysteryRmbShopListLen = 0,
        mysteryRmbShopFlushTime = 0,                                                --珍宝元宝商店系统刷新时间
        mysteryRmbShopFlushCnt = 0,                                                 --珍宝元宝商店刷新次数

        mysteryPrestigeShopList = {child_template = {index = 0, state = 0, curCount = 0, itemID = 0}},        --珍宝威望商店
        mysteryPrestigeShopListLen = 0,
        
        mysteryHonorShopList = {child_template = {index = 0, state = 0, curCount = 0, itemID = 0}},           --珍宝荣誉商店
        mysteryHonorShopListLen = 0,                                                

        zhangongHistory = 0,

        jumpValue = 0,       --跳跃值

        --悬赏任务相关
        bountyDoCnt = 0,
        bountyLv = 0,
        bountyFreeTimes = 0,
        bountyRefreshTime = 0,
        bountyCanDoList ={},
        bountyCanDoListLen = 0,
        bountyAddCnt = 0,

        item_use_cnt = {child_template = {itemid = 0, cnt = 0}},        --物品每日使用次数统计
        item_use_cntLen = 0,
        item_use_group = {child_template = {group = 0, cnt = 0}},        --物品每日组使用次数统计
        item_use_groupLen = 0,
        item_use_cool = {child_template = {group = 0, usetime = 0}},    --物品使用冷却
        item_use_coolLen = 0,
        
        attr_item = {child_template= {itemid= 0, cnt =0}}, -- 属性果实使用计数
        attr_itemLen = 0,
        
        shopLimtiCnt = {}, --商城限购数量
        
        pet={child_template={lv=0,exp=0,id=0,hp=0,status=0,star=0,stage=0,equipStatus={[0]=0,0,0,0},feedAttrVal = {[0] = 0,0,0,0,0,0,0,0,}, skillLv={[0]=0,0,0,0}, zhandouli = 0, next_create_time = 0}, addRolePower = 0, startTime = 0, limitTime=0}, --宠物
        petLen = 0,
        petCombatId = 0,
        petAtticLv = 0, --神将阁等级
        petAtticPro = 0, --神将阁进度
        
        loginKeepDay = 0, --登录天数
        loginChange = 0, --是否是第一个登录计数
        fuliIsGet = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, --福利大厅领取状态
        signDay = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},   --签到状态
        investRMB = 0,  --投资了那个元宝种类
        findCowryTimes = 0, --锦囊寻宝次数，每日更新
        cowryBag = {},      --寻宝仓库
        cowryBagLen = 0,    --寻宝仓库个数
        onLineSeconds = 0, --在线时间（秒） 
        cowrySpecTimes = 0, --普通物品抽中次数
        cowryGetMaxCnt = {child_template = {maxGetIndex = 0, maxGetTimes = 0}}, --道具每日最大抽中次数
        cowryGetMaxCntLen = 0, --长度
        cowryRecord = {child_template = {id =0 , cnt = 0, bind = 1}},
        cowryRecordLen = 0,
        fuliGrowBuyTimes = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, --成长特惠购买次数
        
        rmbSmeltTimes = 0, --元宝熔炼次数
        rmbSmelthelpTimes = 0, --帮助他人次数
        rmbSmeltIsPut = 0,    --是否已投入元宝
        yestdaySmeltTimes =0, --昨天熔炼多少次
        humanSet = 35071,       --设置，前端使用
        
        actValue = 0, --活跃度
        actValueRecord = {child_template={id=0, cnt = 0}}, --活跃度记录
        actValueRecordLen = 0,
        actValueRewardOk = 0,   --活跃度奖励已领最高
        pata_cur  = 1,     --当前要爬塔层数
        pata_max  = 0,     --历史最高层
        pata_reset = 0,    --当前重置次数
        pata_add  = 0,     --VIP5增加重置次数
        pata_ko   = 0,     --已扫荡次数
        pata_store = {},   --斩将仓库
        pata_storeLen = 18, 
        pata_first = {[0]=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},    -- pata首通奖励领取状态
        pata_first_die = 0,	--爬塔首次死亡奖励
        
        monthCard = {[0]={startTime=0, isGet = 0, times = 0},{startTime=0, isGet = 0, times = 0}}, --月卡
        vipRewardIsGet = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0},
        monthCardAddBag = 0,
        
        worship = {child_template={ uuid = ""}},
        worshipLen = 0,
        worshipedTimes = 0, --被膜拜次数
        
        wsAddTimes = 0,  --无双战域已购买次数
        remainTZ = 0,    --无双战域剩余挑战值
        
        dailyChongzhi = 0; --每日累计充值
        openActStatus = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, --开服活动奖励状态
        openActBuyTimes = {[0] = 0,0,0,0,0,0,0,0},
        dailyCostBindYunabao = 0, --每日消费的绑定元宝
        openActDrawTimes = 0, --开服活动抽奖次数
        openActDrawTotalTimes = 0, --开服活动总的抽奖次数
        
        autoUseDrugPer = 60, --生命值达到多少自动使用药品
        killerType = 0,        
        wsslTime = 0,     --武圣试炼进入时间。
        
        offlinePkRank = 0,       --离线竞技场排名
        offlinePkRewardRank = 0, --离线竞技场奖励结算时排名;
        offlinePkHistoryRank = 0,--历史最高排名
        offlinePkTime = 0,       --离线竞技场上次PK时间
        offlinePkLogs = {child_template={name="", time=0,win=0,result = 0,rank=0, active = 0}},  --离线竞技日志
        offlinePkLogsLen = 0,
        jzwarEnterTime = 0,
        dhfightEnterTime = 0,
        ccjjwarEnterTime = 0,
        
        yellowNewReward = 0,  --黄钻新手奖励
        yellowLvReward = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},--黄钻等级奖励
        yellowDailyReward = {[0] = 0,0,0,0,0,0,0,0,0,0}, --黄钻每日奖励
        
        tgpNew = 0,			-- tgp特权礼包
        tgpLv = {[0] = 0,0,0,0,0,0,0,0,0,0},
        tgpDaily = 0,
        tgpWeek = 0,
        
        riotContribution = 0, --叛军暴动个人贡献
        riotFamilyExp = 0, --叛军暴动个人军团经验
        
        reviveNowTime = 0,
        reviveNowItemNum= 0,
        
        xlLv = {child_template={lv=1,exp=0},[0]={lv=1,exp=0},{lv=1,exp=0},{lv=1,exp=0},{lv=1,exp=0},{lv=1,exp=0},{lv=1,exp=0},{lv=1,exp=0},
        {lv=1,exp=0},{lv=1,exp=0},{lv=1,exp=0},{lv=1,exp=0},{lv=1,exp=0},{lv=1,exp=0}}, --洗练等级
        xlLvLen = 13,
        
        appContractId = "", --QQ任务集市ID
        appContractIdStatus = 0, --状态
        
        baowu = {child_template={id =0, lv = 0, starLv = 0, exp = 0, skillId = 0, skillLv =0, status = 0, power = 0, LonghunLv = 0, leftSkillId = 0,rightSkillId = 0, startTime = 0, limitTime = 0}},
        baowuLen = 0,
        combatBaowu = 0,
        
        YYActivityId = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, --运营活动版本号
        YYChongzhiRebate = {[0] = 0,0,0,0,0,0,0,0,0,0},
        YYChongzhiDrawTimes = 0, --运营活动充值抽奖次数
        YYCritDrawTimes = 0, --运营活动暴击轮盘抽奖次数
        YYLimitBuyTimes = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, --运营活动珍品抢购购买次数
        YYDaBiaoStatus = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, --运营活动达标领取状态
        YYPayDrawStatus = {[0] = 0,0,0,0,0,0,0,0,0,0},  --运营活动消费转盘奖励状态
        YYPayDrawTimes = 0, --运营活动消费转盘抽奖次数
        
        skillItemList = {[0] = 0, 0},
        
        YYCopyFastIsGet = 0, --运营活动副本速成奖励是否领取
        YYActivityPlayIsGet = {[0]=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, --运营活动活动畅玩是否领取
        
        copyFind = {child_template={id = 0, copyFreeFindTimes = 0, copyYuanbaoFindTimes = 0, copyYestdayFreeFindTimes = 0 ; copyYestdayYuanbaoFindTimes = 0}},  --副本找回次数
        copyFindLen = 0,
        ActFind = {child_template={id = 0, actFindType = 0, actYestdayFindType = 0, actYuanbaoFindType = 0, actYuanbaoYestdayFindType = 0}},  --副本找回次数
        ActFindLen = 0,
        
        ChongzhiPresentCnt = 0, -- 充值豪礼活动领取次数
        dailyCostYuanbao = 0, --每日累计消费
        
        activateHis = {child_template={type = 0, sumCnt = 0, dailyCnt = 0, getTime = 0}},
		    activateHisLen = 0,
		    
        blueNewReward = 0,  --蓝钻新手奖励
        blueLvReward = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},--蓝钻等级奖励
        blueDailyReward = {[0] = 0,0,0,0,0,0,0,0,0,0}, --蓝钻每日奖励
        
        level3366CanGet = {[0] = 0,0,0,0,0,0},  --3366奖励
        
        DateActivityId = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, --活动规则id
        DateCritDrawTimes = 0, --运营活动暴击轮盘抽奖次数
        DateLimitBuyTimes = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, --运营活动珍品抢购购买次数
        DateChongzhiRebate = {[0] = 0,0,0,0,0,0,0,0,0,0},
        DatePayDrawStatus = {[0] = 0,0,0,0,0,0,0,0,0,0},
        DatePayDrawTimes = 0,

        curarmourid = 0,    --当前穿戴战甲
        armourlist  = {child_template={armourid = 0, lv = 0, star = 0, state = 1, feedAttr={[0]=0,0,0,0,0,0,0,0}}},  --战甲列表
        armourlistLen = 0,
        
        dailyGiftStatus = 0, --每日豪礼奖励
        dailyGiftThirdID = 0, --每日豪礼随机道具ID
        
        yaoshuList = {child_template = {id = 0, skillLv = 0, status = 0}}, --要术信息
        yaoshuListLen = 0, --要术长度
        combatYaoshu = 0, --当前使用的要术
        QiliaoSkillLv = 0, --气疗主技能等级
        dhfightcurfloor = 0, --大汉格斗场层数记录
        
        taoyuanLastFreeTime = 0, --上次免费桃园结义时间
        taoyuanReward = {[0]=0, 0, 0, 0,0}, 
        taoyuanVersion = 0,
        
        canFindExpHour = 0, --可找回几个小时的经验
        
        titleList = {child_template={id = 0, createTime = 0}}, -- 称号
        titleListLen = 0,
        titleSelectID = 0,  --当前选择的ID
        
        officialTarget = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, --军衔已完成的目标
        officialRewardIsGet = 0, --军衔日常奖励是否领取
        officialLv = 0, --军衔等级
    }
    for i=0, ShopHelp.SHOP_LIMIT_BUY_MAX_CNT - 1 do
      db.shopLimtiCnt[i] = 0
    end
    
    if template then
        return db
    end
    del_child_template(db)      --不是模板数据，删掉child_template字段
    db.taskRecord[0] = {}
    db.taskRecord[0].taskid = 10 --接第一个任务
    db.taskRecord[0].status = 1
    db.taskRecord[0].params = {}
    db.taskRecord[0].paramsLen = 0
    db.taskRecordLen = 1
    
    db.stageHorseLen = 10
    for i=0, 9 do
      db.stageHorse[i] = {}
      db.stageHorse[i].equipQua = 0
      db.stageHorse[i].equipId = {}
      for j=0,3 do
        db.stageHorse[i].equipId[j] = 0
      end
    end
    
    db.bag[0] = {}
    Grid.create(db.bag[0],10040,20,true)
    
    return db
end

char_db_template = char_db_template or get_default_db(true)


function copy_ffi_to_db(ffi_db, db, template)
    if not template then
        template = char_db_template
    end
    for k, v  in pairs(template) do
        if k == "bag" or k == "store" or k == "equip" or k == "pata_store" or k == "cowryBag" then  --grid特殊处理
            local len = ffi_db[k.."Len"]
            for i = 0, len -1 do
                if ffi_db[k][i].id ~= 0 then
                    db[k][i] = db[k][i] or {}
                    Grid.copy(db[k][i], ffi_db[k][i], true)
                end
            end
        elseif type(v) == "string" then
            db[k] = ffi_string(ffi_db[k])
        elseif type(v) == "table" then
            local kk = k.."Len"
            if template[kk] then
                -- 数组形式
                db[k] = {}
                for i = 0, ffi_db[kk] -1 do
                    if v.child_template then
                        local vv = {}
                        copy_ffi_to_db(ffi_db[k][i], vv, v.child_template)
                        db[k][i] = vv
                    else
                        db[k][i] = ffi_db[k][i]
                    end
                end
            else
                local vv = {}
                copy_ffi_to_db(ffi_db[k], vv, v)
                db[k] = vv
            end
        else
            db[k] = ffi_db[k]
        end
    end
end
function copy_db_to_ffi(db, ffi_db, template)
    for k, v  in pairs(template) do
        if k == "bag" or k == "store" or k == "equip" or k == "pata_store" or k == "cowryBag" then
            local len = db[k.."Len"] or 0
            for i = 0, len-1 do
                if db[k][i] == nil then
                    ffi_db[k][i].id = 0
                else
                    Grid.copy(ffi_db[k][i], db[k][i])
                end
            end
        elseif k ~= "child_template" then
            if type(v) == "table" then
                local kk = k.."Len"
                if template[kk] then
                    db[kk] = db[kk] or template[kk]
                    for i = 0, db[kk] - 1 do
                        if v.child_template then
                            copy_db_to_ffi(db[k][i], ffi_db[k][i], v.child_template)
                        else
                            ffi_db[k][i] = db[k][i] or 0
                        end
                    end
                else
                    copy_db_to_ffi(db[k], ffi_db[k], v)
                end
            else
                ffi_db[k] = db and db[k] or v
            end
        end
    end
end
function create_ffi(db, fd, ffi2ffi)
    if _G.is_world == nil then
        assert(0)
    end
    if ffi2ffi then
        ffi.C.role_add(db,fd)
        return db
    end
    local r = ffi.C.role_alloc()
    if r > nil then
        local role = ffi.cast('role*', r)
        copy_db_to_ffi(db, role, char_db_template)
        ffi.C.role_add(r, fd)
        return role
    else
        assert(0)
    end
end

function copy2ffi(ffi, db)
    copy_db_to_ffi(db, ffi, char_db_template)
end

function destroy_ffi(role)
    if _G.is_world == nil then
        assert(0)
    end
    ffi.C.role_free(role)
end


function find_ffi_by_fd(fd)
    if _G.is_world then
        assert(0)
    end
    local r = ffi.C.find_role_by_fd(fd)
    if r > nil then
        local role = ffi.cast('role*', r)
        return role
    end
end

function ffi_string(s)
    return s and ffi.string(s) or ""
end


function copy_array_element(arr, dst,src, type)
    local r = ffi.cast(type.."*", arr)
    ffi.C.role_copy(r+dst, r+src, ffi.sizeof(type))
end

function memset_zero(p, type)
    ffi.C.memset_zero(ffi.cast(type.."*", p), ffi.sizeof(type))
end
